# -*- coding: utf-8 -*-
from api import api, GlobalError, ERROR_STUDIO
from flask import jsonify, request
from model.answer import Answer
from model.article import Article
from model.problem import Problem
from model.recruitment import Recruitment
from model.studio_comment import StudioComment
from model.studio import Studio
from model.user import User
from model.video import Video
from pymongo.errors import DuplicateKeyError
from time import time
from util.user_helper import get_user_or_studio_from_id
from werkzeug.exceptions import NotFound
from util.removeNBSP import removeNBSP
import json, re


class Error:
    STUDIO_EXISTS = {
        'err': ERROR_STUDIO + 1,
        'msg': 'Studio Exists'
    }


@api.route('/studios', methods=['GET'])
def get_all_studio():
    '''
## 获取画室详情

    GET /api/studios

Parameters:

* `skip` (int, optional)
* `total` (int, optional)
* `userId` (string, optional)

Return:

* `studios` (list of dict)
    * `studioId` (string) - 画室 ID
    * `answerNum` (int)
    * `articleNum` (int)
    * `avatarUrl` (string) - 画室头像链接
    * `createTime` (long) - 画室创建的时间
    * `description` (string) - 画室的描述
    * `email` (string) - 画室账号邮箱
    * `fanNum` (int)
    * `followNum` (int)
    * `isWatched` (int) - 0表示未关注，1表示关注
    * `name` (string) - 画室名称，该名称唯一
    * `phone` (string) - 画室的号码
    * `password` (string) - 用于登陆画室的密码
    * `teacherNum` (int)
    * `videoNum` (int)
    * `register` (int) - 1 表示画室通过验证， 0 表示不通过
    * `workNum` (int)
    '''
    skip = request.args.get('skip', 0, type=int)
    total = request.args.get('total', 20, type=int)
    user_id = request.args.get('userId', None)
    try:
        studio_list = Studio.find({}, {
            Studio.Field.password: 0,
            Studio.Field.answer: 0,
            Studio.Field.article: 0,
            Studio.Field.fan: 0,
            Studio.Field.follow: 0,
            Studio.Field.teacher: 0,
            Studio.Field.video: 0,
            Studio.Field.work: 0
        }, skip=skip, limit=total)
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403

    if user_id:
        try:
            user = User.get({
                User.Field._id: user_id
            }, [
                User.Field.follow
            ])
        except NotFound:
            return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403

    studios = []
    for studio in studio_list:
        studio['studioId'] = studio.get(Studio.Field._id)
        del studio[Studio.Field._id]
        studio['isWatched'] = 0
        if user_id:
            if studio['studioId'] in user.data.get(User.Field.follow):
                studio['isWatched'] = 1
        studios.append(studio)

    return jsonify(stat=1, studios=studios)


@api.route('/studio', methods=['POST'])
def new_studio():
    '''
## 创建画室

    POST /api/studio

Parameters:

* `email` (string, required) - 邮箱
* `password` (string, required) - 密码

Return:

* `studioId` (string)

Errors: `5`, `7001`
    '''
    email = request.form.get('email', None)
    password = request.form.get('password', None)
    if email is None or password is None:
        return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403

    try:
        studio_id = Studio.new_studio(email, password)
    except DuplicateKeyError:
        return jsonify(stat=0, **Error.STUDIO_EXISTS), 403
    return jsonify(stat=1, studioId=studio_id)


@api.route('/studio/login', methods=['POST'])
def studio_login():
    '''
## 画室登录

    POST /api/studio/login

Parameters:

* `email` (string, required) - 邮箱
* `password` (string, required) - 密码

Return:

* `studioId` (string) - 画室 ID
* `answerNum` (int)
* `articleNum` (int)
* `avatarUrl` (string) - 画室头像链接
* `createTime` (long) - 画室创建的时间
* `description` (string) - 画室的描述
* `email` (string) - 画室账号邮箱
* `fanNum` (int)
* `followNum` (int)
* `name` (string) - 画室名称，该名称唯一
* `phone` (string) - 画室的号码
* `password` (string) - 用于登陆画室的密码
* `teacherNum` (int)
* `videoNum` (int)
* `register` (int) - 1 表示画室通过验证， 0 表示不通过
* `workNum` (int)
    '''
    email = request.form.get('email', None)
    password = request.form.get('password', None)
    if email is None or password is None:
        return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403

    try:
        studio = Studio.get({
            Studio.Field.email: email
        }, {
            Studio.Field.answer: 0,
            Studio.Field.article: 0,
            Studio.Field.fan: 0,
            Studio.Field.follow: 0,
            Studio.Field.teacher: 0,
            Studio.Field.video: 0,
            Studio.Field.work: 0
        })
    except NotFound:
        return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403
    passwd = studio.data.get(Studio.Field.password)
    if passwd != Studio.get_hashed_password(password):
        return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403
    studio.data['studioId'] = studio.data.get(Studio.Field._id)
    del studio.data[Studio.Field._id]
    del studio.data[Studio.Field.password]
    return jsonify(stat=1, studio=studio.data)


@api.route('/studio/<studio_id>', methods=['GET'])
def get_studio(studio_id):
    '''
## 获取画室详情

    GET /api/studio/<studio_id>

Parameters:

* `userId` (string, optional)

Return:

* `studioId` (string) - 画室 ID
* `answerNum` (int)
* `articleNum` (int)
* `avatarUrl` (string) - 画室头像链接
* `createTime` (long) - 画室创建的时间
* `description` (string) - 画室的描述
* `email` (string) - 画室账号邮箱
* `fanNum` (int)
* `followNum` (int)
* `isWatched` (int) - 0表示未关注，1表示关注
* `name` (string) - 画室名称，该名称唯一
* `phone` (string) - 画室的号码
* `city` (dict) - 画室地区
* `teacherNum` (int)
* `videoNum` (int)
* `register` (int) - 1 表示画室通过验证， 0 表示不通过
* `workNum` (int)
    '''
    user_id = request.args.get('userId', None)
    try:
        studio = Studio.get({
            Studio.Field._id: studio_id
        }, {
            Studio.Field.answer: 0,
            Studio.Field.article: 0,
            Studio.Field.fan: 0,
            Studio.Field.follow: 0,
            Studio.Field.teacher: 0,
            Studio.Field.video: 0,
            Studio.Field.work: 0
        })
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403

    if user_id:
        try:
            user = User.get({
                User.Field._id: user_id
            }, [
                User.Field.follow
            ])
        except NotFound:
            return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403

    studio.data['studioId'] = studio_id
    studio.data[Studio.Place.city] = studio.data.get(Studio.Field.place).get(Studio.Place.city)
    del studio.data[Studio.Field._id]
    del studio.data[Studio.Field.password]
    studio.data['isWatched'] = 0
    if user_id:
        if studio.data.get('studioId') in user.data.get(User.Field.follow):
            studio.data['isWatched'] = 1

    return jsonify(stat=1, studio=studio.data)


@api.route('/studio/<studio_id>/article', methods=['GET'])
def get_studio_article(studio_id):
    '''
## 获取画室文章

    GET /api/studio/<studio_id>/article

Parameters:

* `skip` (int, optional)
* `total` (int, optional) - 返回个数，默认为20，-1表示返回全部
* `b_web` (boolean, optional) - 如果有传，表示是B端的请求，要保留html标签，app端则要去掉
Return :

* `articles` (list of dict)
    * `content` (string)
    * `createTime` (long)
    * `images` (list of string) - 文章图片链接
    * `studioId` (string)
    * `title` (string)
    * `viewNum` (int)
    '''
    skip = request.args.get('skip', 0, type=int)
    total = request.args.get('total', 20, type=int)
    b_web = request.args.get('b_web', None, type=int)

    try:
        studio = Studio.get({
            Studio.Field._id: studio_id
        }, [
            Studio.Field.article,
            Studio.Field.articleNum
        ])
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403

    articles = []
    article_list = studio.data.get(Studio.Field.article, [])[skip:skip + total] if total != -1 else studio.data.get(Studio.Field.article, [])[skip:]
    for article_id in article_list:
        try:
            article = Article.get({
                Article.Field._id: article_id
            }, [
                Article.Field.content,
                Article.Field.createTime,
                Article.Field.images,
                Article.Field.studioId,
                Article.Field.title,
                Article.Field.viewNum
            ])
        except:
            continue
        article.data['articleId'] = article_id
        del article.data[Article.Field._id]
        article.data[Article.Field.content] = removeNBSP(article.data[Article.Field.content], b_web)
        articles.append(article.data)
    return jsonify(stat=1, articles=articles)


@api.route('/studio/<studio_id>/fan', methods=['GET'])
def get_studio_fan(studio_id):
    '''
## 获取画室粉丝

    GET /api/studio/<studio_id>/fan

Parameters:

* `skip` (int, optional)
* `total` (int, optional) - 返回个数，默认为20
* `userId` (string, optional) - 当前登录用户 ID

Return:

* `fans` (list of dict)
    * `userId` (string)
    * `avatarUrl` (string)
    * `name` (string)
    * `relation` (int) - 0表示当前登录用户未关注，1表示已关注
    * `uType` (int) - 0表示学生，1表示教师，2表示画室
    '''
    skip = request.args.get('skip', 0, type=int)
    total = request.args.get('total', 20, type=int)
    try:
        studio = Studio.get({
            Studio.Field._id: studio_id
        }, [
            Studio.Field.fan,
            Studio.Field.fanNum
        ])
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403
    user_id = request.args.get('userId', None)
    if user_id is not None:
        try:
            user = User.get({
                User.Field._id: user_id
            }, [
                User.Field.follow
            ])
            follow_list = user.data.get(User.Field.follow)
        except NotFound:
            return jsonify(stat=0, **GlobalError.INVALID_USER_ID), 403

    fans = []
    for fan_id in studio.data.get(Studio.Field.fan, [])[skip:skip + total]:
        try:
            user = User.get({
                User.Field._id: fan_id
            }, [
                User.Field.avatarUrl,
                User.Field.name,
                User.Field.isTeacher
            ])
        except:
            continue

        user.data['userId'] = fan_id
        del user.data[User.Field._id]
        if user_id:
            user.data['relation'] = 0
            if fan_id in follow_list:
                user.data['relation'] = 1
        user.data['uType'] = 0
        if user.data.get(User.Field.isTeacher):
            user.data['uType'] = 1
        fans.append(user.data)
    return jsonify(stat=1, fans=fans)


@api.route('/studio/<studio_id>/follow', methods=['GET'])
def get_studio_follow(studio_id):
    '''
## 获取画室关注的人

    GET /api/studio/<studio_id>/follow

Parameters:

* `skip` (int, optional)
* `total` (int, optional) - 返回个数，默认为20
* `userId` (string, optional) - 当前登录用户 ID

Return:

* `follows` (list of dict)
    * `userId` (string)
    * `avatarUrl` (string)
    * `name` (string)
    * `relation` (int) - 0表示当前登录用户未关注，1表示已关注
    * `uType` (int) - 0表示学生，1表示教师，2表示画室
    '''
    skip = request.args.get('skip', 0, type=int)
    total = request.args.get('total', 20, type=int)
    try:
        studio = Studio.get({
            Studio.Field._id: studio_id
        }, [
            Studio.Field.follow,
            Studio.Field.followNum
        ])
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403
    user_id = request.args.get('userId', None)
    if user_id:
        try:
            user = User.get({
                User.Field._id: user_id
            }, [
                User.Field.follow
            ])
            follow_list = user.data.get(User.Field.follow)
        except NotFound:
            return jsonify(stat=0, **GlobalError.INVALID_USER_ID), 403

    follows = []
    for follow_id in studio.data.get(Studio.Field.follow, [])[skip: skip + total]:
        try:
            user = User.get({
                User.Field._id: follow_id
            }, [
                User.Field.avatarUrl,
                User.Field.name,
                User.Field.isTeacher
            ])
        except:
            continue
        user.data['userId'] = follow_id
        del user.data[User.Field._id]
        if user_id:
            user.data['relation'] = 0
            if follow_id in follow_list:
                user.data['relation'] = 1
        user.data['uType'] = 0
        if user.data.get(User.Field.isTeacher):
            user.data['uType'] = 1
        follows.append(user.data)
    return jsonify(stat=1, follows=follows)


@api.route('/studio/<studio_id>/teacher', methods=['GET'])
def get_studio_teacher(studio_id):
    '''
## 获取画室的教师

    GET /api/studio/<studio_id>/teacher

Parameters:

* `skip` (int, optional)
* `total` (int, optional) - 返回个数，默认为20

Return:

* `teachers` (list of dict)
    * `userId` (string)
    * `avatarUrl` (string)
    * `name` (string)
    '''
    skip = request.args.get('skip', 0, type=int)
    total = request.args.get('total', 20, type=int)
    try:
        studio = Studio.get({
            Studio.Field._id: studio_id
        }, [
            Studio.Field.teacher,
            Studio.Field.teacherNum
        ])
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403

    teachers = []
    for teacher_id in set(studio.data.get(Studio.Field.teacher, [])[skip:skip + total]):
        try:
            user = User.get({
                User.Field._id: teacher_id
            }, [
                User.Field.avatarUrl,
                User.Field.name
            ])
        except:
            continue
        user.data['userId'] = teacher_id
        del user.data[User.Field._id]
        teachers.append(user.data)
    return jsonify(stat=1, teachers=teachers)


@api.route('/studio/<studio_id>/video', methods=['GET'])
def get_studio_video(studio_id):
    '''
## 获取画室视频

    GET /api/studio/<studio_id>/video

Parameters:

* `skip` (int, optional)
* `total` (int, optional)

Return:

* `videos` (list of dict)
    * `createTime` (long)
    * `title` (string)
    * `description` (string)
    * `imageUrl` (string)
    * `updateTime` (long)
    * `userId` (string) - 可能为空
    * `videoId` (string)
    * `videoUrl` (string) - 视频链接
    '''
    skip = request.args.get('skip', 0, type=int)
    total = request.args.get('total', 20, type=int)
    try:
        studio = Studio.get({
            Studio.Field._id: studio_id
        }, [
            Studio.Field.video,
            Studio.Field.videoNum
        ])
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403

    videos = []
    for video_id in studio.data.get(Studio.Field.video, [])[skip: skip + total]:
        try:
            video = Video.get({
                Video.Field._id: video_id
            }, [
                Video.Field.createTime,
                Video.Field.title,
                Video.Field.description,
                Video.Field.imageUrl,
                Video.Field.updateTime,
                Video.Field.userId,
                Video.Field.videoUrl
            ])
        except:
            continue
        video.data['videoId'] = video_id
        del video.data[Video.Field._id]
        videos.append(video.data)
    return jsonify(stat=1, videos=videos)


@api.route('/studio/<studio_id>/work', methods=['GET'])
def get_studio_work(studio_id):
    '''
## 获取画室作品

    GET /api/studio/<studio_id>/work

Parameters:

* `skip` (int, optional)
* `total` (int, optional)

Return:

* `works` (list of string)
    '''
    skip = request.args.get('skip', 0, type=int)
    total = request.args.get('total', 20, type=int)
    try:
        studio = Studio.get({
            Studio.Field._id: studio_id
        }, [
            Studio.Field.work,
            Studio.Field.workNum
        ])
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403

    return jsonify(stat=1, works=studio.data.get(Studio.Field.work, [])[skip:skip + total])


@api.route('/studio/<studio_id>/recruitment', methods=['GET'])
def get_studio_recruiment(studio_id):
    '''
## 获取该画室所有招聘信息

    GET /api/studio/<studio_id>/recruitment

Return:

* `recruitments` (list of dict)
    * `recruitmentId` (string)
    * `description` (string)
    * `salary` (string)
    * `title` (string)
    * `updateTime` (long) - 最后更新时间
    '''
    try:
        studio = Studio.get({
            Studio.Field._id: studio_id
        }, [
            Studio.Field.recruitment
        ])
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403
    recruitments = []
    recruitment_list = Recruitment.find({
        Recruitment.Field._id: {
            '$in': studio.data.get(Studio.Field.recruitment, [])
        }
    })
    for recruitment in recruitment_list:
        recruitments.append({
            'recruitmentId': recruitment.get(Recruitment.Field._id),
            Recruitment.Field.title: recruitment.get(Recruitment.Field.title),
            Recruitment.Field.description: recruitment.get(Recruitment.Field.description),
            Recruitment.Field.salary: recruitment.get(Recruitment.Field.salary),
            Recruitment.Field.updateTime: recruitment.get(Recruitment.Field.updateTime)
        })
    return jsonify(stat=1, recruitments=recruitments)


@api.route('/studio/<studio_id>/teacher', methods=['PUT', 'DELETE'])
def update_studio_teacher(studio_id):
    '''
## 画室操作教师

    添加 PUT /api/studio/<studio_id>/teacher
    删除 DELETE /api/studio/<studio_id>/teacher

Parameters:

* `userId` (string, required) - userId 与 userName 两者提供一者即可
* `userName` (string, required) - userId 与 userName 两者提供一者即可
    '''
    teacher_id = request.form.get('userId', None) or request.args.get('userId', None)
    teacher_name = request.form.get('userName', None) or request.args.get('userName', None)
    if teacher_id is None and teacher_name is None:
        return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403

    try:
        studio = Studio.get({
            Studio.Field._id: studio_id
        }, [])
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403

    query = {}
    if teacher_id:
        query[User.Field._id] = teacher_id
    elif teacher_name:
        query[User.Field.name] = teacher_name
    try:
        teacher = User.get(query)
        teacher_id = teacher.data.get(User.Field._id)
    except NotFound:
        return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403

    if request.method == 'PUT':
        teacher.update({
            '$set': {
                User.Field.studioId: studio_id,
                User.Field.isTeacher: 1
            }
        })
    elif request.method == 'DELETE':
        teacher.update({
            '$set': {
                User.Field.studioId: '',
                User.Field.isTeacher: 0
            }
        })

    update_info = {}
    if request.method == 'PUT':
        update_info['$push'] = {Studio.Field.teacher: teacher_id}
        update_info['$inc'] = {Studio.Field.teacherNum: 1}
    elif request.method == 'DELETE':
        update_info['$pull'] = {Studio.Field.teacher: teacher_id}
        update_info['$inc'] = {Studio.Field.teacherNum: -1}
    studio.update(update_info)

    return jsonify(stat=1)


@api.route('/studio/<studio_id>/video', methods=['PUT', 'DELETE'])
def update_studio_video(studio_id):
    '''
## 画室操作视频

    添加 PUT /api/studio/<studio_id>/video
    删除 DELETE /api/studio/<studio_id>/video

Parameters:

* `videoId` (string, required)
    '''
    video_id = request.form.get('videoId', None) or request.args.get('videoId', None)
    if video_id is None:
        return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403
    try:
        studio = Studio.get({
            Studio.Field._id: studio_id
        }, [])
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403
    try:
        video = Video.get({
            Video.Field._id: video_id
        }, [])
    except NotFound:
        return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403

    if request.method == 'PUT':
        video.update({
            '$set': {
                Video.Field.studioId: studio_id
            }
        })
    elif request.method == 'DELETE':
        video.update({
            '$set': {
                Video.Field.studioId: ''
            }
        })
    update_info = {}
    if request.method == 'PUT':
        update_info['$push'] = {Studio.Field.video: video_id}
        update_info['$inc'] = {Studio.Field.videoNum: 1}
    elif request.method == 'DELETE':
        update_info['$pull'] = {Studio.Field.video: video_id}
        update_info['$inc'] = {Studio.Field.videoNum: -1}
    studio.update(update_info)

    return jsonify(stat=1)


@api.route('/studio/<studio_id>/work', methods=['PUT'])
def update_studio_work(studio_id):
    '''
## 画室操作作品

    添加 PUT /api/studio/<studio_id>/work

Parameters:

* `imageUrls` (list of string, required)
    '''
    image_urls = request.form.get('imageUrls', None)
    image_urls = json.loads(image_urls)
    if image_urls is None:
        return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403
    try:
        studio = Studio.get({
            Studio.Field._id: studio_id
        }, [
            Studio.Field.work
        ])
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403

    work_list = studio.data.get(Studio.Field.work)

    image_urls = filter(lambda x: x not in work_list, image_urls)

    studio.update({
        '$push': {
            Studio.Field.work: {
                '$each': image_urls,
                '$position': 0
            }
        },
        '$inc': {
            Studio.Field.workNum: len(image_urls)
        }
    })

    return jsonify(stat=1)


@api.route('/studio/<studio_id>/work', methods=['DELETE'])
def delete_studio_work(studio_id):
    '''
## 画室操作作品

    删除 DELETE /api/studio/<studio_id>/work

Parameters:

* `imageUrl` (string, required)
    '''
    image_url = request.args.get('imageUrl', None) or request.form.get('imageUrl', None)
    if image_url is None:
        return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403
    try:
        studio = Studio.get({
            Studio.Field._id: studio_id
        }, [
            Studio.Field.work
        ])
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403

    work_list = studio.data.get(Studio.Field.work)

    if image_url not in work_list:
        return jsonify(stat=1)

    studio.update({
        '$pull': {
            Studio.Field.work: image_url
        },
        '$inc': {
            Studio.Field.workNum: -1
        }
    })

    return jsonify(stat=1)


@api.route('/studio/<studio_id>/info', methods=['PUT'])
def update_studio_info(studio_id):
    '''
## 更新画室详情

    PUT /api/studio/<studio_id>/info

Parameters:

* `name` (string, optional)
* `description` (string, optional)
* `province` (string, optional)
* `city` (string, optional)
* `phone` (string, optional)
    '''
    name = request.form.get('name', None)
    description = request.form.get('description', None)
    province = request.form.get('province', None)
    city = request.form.get('city', None)
    phone = request.form.get('phone', None)

    update_info = {}
    update_info['$set'] = {}
    if name is not None:
        update_info['$set'][Studio.Field.name] = name
    if phone is not None:
        update_info['$set'][Studio.Field.phone] = phone
    if description is not None:
        update_info['$set'][Studio.Field.description] = description
    if province is not None:
        if not update_info.get(Studio.Field.place):
            update_info['$set'][Studio.Field.place] = {}
        update_info['$set'][Studio.Field.place][Studio.Place.province] = province
    if city is not None:
        if not update_info.get(Studio.Field.place):
            update_info['$set'][Studio.Field.place] = {}
        update_info['$set'][Studio.Field.place][Studio.Place.city] = city

    try:
        Studio.collection.update({
            Studio.Field._id: studio_id
        }, update_info)
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403
    except:
        return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403

    return jsonify(stat=1)


@api.route('/studio/<studio_id>/recruitment', methods=['PUT', 'DELETE'])
def update_studio_recruitment(studio_id):
    '''
## 更新招聘信息

    更新 PUT /api/studio/<studio_id>/recruitment
    删除 DELETE /api/studio/<studio_id>/recruitment

Parameters:

* `recruitmentId` (string, required)
* `title` (string, optional)
* `salary` (string, optional)
* `description` (string, required)

Return:

* `title` (string): 标题
* `salary` (string): 工资
* `description` (string): 描述
    '''
    recruitment_id = request.form.get('recruitmentId', None) or request.args.get('recruitmentId', None)
    if recruitment_id is None:
        return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403

    if request.method == 'DELETE':
        Studio.collection.updat({
            Studio.Field._id: studio_id
        }, {
            '$pull': {
                Studio.Field.recruitment: recruitment_id
            }
        })
        Recruitment.remove({Recruitment.Field._id: recruitment_id})
        return jsonify(stat=1)

    try:
        recruitment = Recruitment.get({
            Recruitment.Field._id: recruitment_id
        }, [])
    except NotFound:
        return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403
    update_info = {}
    title = request.form.get('title', None)
    if title is not None:
        update_info[Recruitment.Field.title] = title
    salary = request.form.get('salary', None)
    if salary is not None:
        update_info[Recruitment.Field.salary] = salary
    description = request.form.get('description', None)
    if description is not None:
        update_info[Recruitment.Field.description] = description
    if len(update_info) > 0:
        update_info[Recruitment.Field.updateTime] = int(time() * 1000)
    recruitment.update({
        '$set': update_info
    })

    return jsonify(stat=1, title=title, salary=salary, description=description)


@api.route('/studio/<studio_id>/article', methods=['POST'])
def new_article(studio_id):
    '''
## 创建新文章

    POST /api/studio/<studio_id>/article

Parameters:

* `title` (required) - 标题
* `content` (required) - 内容
* `images` (JSON string, optional) - JSON 序列化的图片链接列表

Return:

* `articleId` (string)
    '''
    title = request.form.get('title', None)
    content = request.form.get('content', None)
    images = json.loads(request.form.get('images'))
    print images
    if title is None or content is None or studio_id is None:
        return  jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403

    try:
        studio = Studio.get({
            Studio.Field._id: studio_id
        })
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403

    article_id = Article.new_article(title, content, images, studio_id)
    studio.update({
        '$push': {
            Studio.Field.article: {
                '$each': [article_id],
                '$position': 0
            }
        },
        '$inc': {
            Studio.Field.articleNum: 1
        }
    })
    return jsonify(stat=1, articleId=article_id)


@api.route('/studio/<studio_id>/recruitment', methods=['POST'])
def new_recruitment(studio_id):
    '''
## 发布新招聘信息

    POST /api/studio/<studio_id>/recruitment

Parameters:

* `description` (string, required)
* `salary` (string, optional)
* `title` (string, required)
    '''
    try:
        studio = Studio.get({
            Studio.Field._id: studio_id
        }, [])
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403
    title = request.form.get('title', None)
    salary = request.form.get('salary', None)
    description = request.form.get('description', None)
    if title is None or description is None or salary is None:
        return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403
    recruitment_id = Recruitment.new_recruitment(title, salary, description)
    studio.update({
        '$push': {
            Studio.Field.recruitment: recruitment_id
        }
    })
    return jsonify(stat=1, recruitmentId=recruitment_id)


@api.route('/studio/<studio_id>/relation/<user_id>', methods=['GET'])
def get_studio_relation(studio_id, user_id):
    '''
## 查询 studio_id 与 user_id 的关系

    GET /studio/<studio_id>/relation/<user_id>

Return:

* `relation` (int) - 0表示无关系，1表示studio_id关注user_id，2表示user_id是studio_id的粉丝，3表示studio_id与user_id互相关注
    '''
    try:
        studio = Studio.get({
            Studio.Field._id: studio_id
        }, [
            Studio.Field.follow,
            Studio.Field.fan
        ])
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_USER_ID), 403
    relation = 0
    if user_id in studio.data.get(Studio.Field.follow):
        relation += 1
    if user_id in studio.data.get(Studio.Field.fan):
        relation += 2

    return jsonify(stat=1, relation=relation)


@api.route('/studio/<studio_id>/askme', methods=['GET'])
def get_studio_ask_me(studio_id):
    """
## 获取所有询问该画室的问题

    GET /api/studio/<studio_id>/askme

Parameters:

* `aType` (int, optional) - 被提问的问题类型，1表示“学员提问”，2表示“画作点评”，默认为1

Return:

* `problems` ([dict]) - list of dict
    * `problemId` (string)
    * `content` (string)
    * `image` (string) - image url of the problem
    * `zan` (int) - the number of zan
    * `viewNum` (int)
    * `answerNum` (int)
    * `timestamp` (long)
    * `userId` (string) - 提问者 ID
    * `name` (string) - name of the user
    * `avatarUrl` (string) - avatar url of the user

Errors: `1`
    """

    a_type = request.args.get('aType', 1, type=int)

    try:
        studio = Studio.get({
            Studio.Field._id: studio_id
        }, [
            Studio.Field.askMeList
        ])
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_USER_ID), 403

    problem_ids = studio.data.get(Studio.Field.askMeList, [])
    ask_me = []
    for problem_id in problem_ids:
        problem = Problem.get({
            Problem.Field._id: problem_id
        }, [
            Problem.Field.content,
            Problem.Field.image,
            Problem.Field.zan,
            Problem.Field.viewNum,
            Problem.Field.answerNum,
            Problem.Field.timestamp,
            Problem.Field.userId
        ])
        if a_type == 1 and problem.data.get(Problem.Field.image):
            continue
        student = User.get({
            User.Field._id: problem.data.get(Problem.Field.userId)
        }, [
            User.Field.name,
            User.Field.avatarUrl
        ])
        ask_me.append({
            'problemId': problem.data.get(Problem.Field._id),
            Problem.Field.content: problem.data.get(Problem.Field.content),
            Problem.Field.image: problem.data.get(Problem.Field.image),
            Problem.Field.zan: problem.data.get(Problem.Field.zan),
            Problem.Field.viewNum: problem.data.get(Problem.Field.viewNum),
            Problem.Field.answerNum: problem.data.get(Problem.Field.answerNum),
            Problem.Field.timestamp: problem.data.get(Problem.Field.timestamp),
            Problem.Field.userId: problem.data.get(Problem.Field.userId),
            User.Field.name: student.data.get(User.Field.name),
            User.Field.avatarUrl: student.data.get(User.Field.avatarUrl)
        })

    return jsonify(stat=1, problems=ask_me)


@api.route('/studio/<studio_id>/answer', methods=['GET'])
def get_studio_answer(studio_id):
    """
## 获取所有该画室已回答问题

    GET /api/studio/<studio_id>/answer

Return:

* `problems` ([dict]) - list of dict
    * `_id` (string)
    * `answer` (string)
    * `answerId` (string)
    * `answerNum` (int)
    * `askTo` (string)
    * `askToAvatarUrl` (string)
    * `askToName` (string)
    * `askToType` (int) - 1表示教师，2表示画室，-1表示无
    * `commentNum` (int)
    * `content` (string)
    * `image` (string) - image url of the problem
    * `zan` (int) - the number of zan
    * `viewNum` (int)
    * `answerNum` (int)
    * `timestamp` (long)
    * `userId` (string) - 提问者 ID
    * `name` (string) - name of the user
    * `avatarUrl` (string) - avatar url of the user

Errors: `1`
    """

    try:
        studio = Studio.get({
            Studio.Field._id: studio_id
        }, [
            Studio.Field.answer
        ])
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403

    answer_ids = studio.data.get(Studio.Field.answer, [])
    answer_list = Answer.find({
        Answer.Field._id: {
            '$in': answer_ids
        }
    })
    answer_list = dict([(answer[Answer.Field._id], answer) for answer in answer_list])
    answer_list = dict([(answer_id, answer_list[answer_id]) for answer_id in answer_ids])
    answers = []
    for answer_id in answer_ids:
        answer = answer_list[answer_id]
        problem = Problem.get({
            Problem.Field._id: answer.get(Answer.Field.problemId)
        }, [
            Problem.Field.content,
            Problem.Field.image,
            Problem.Field.zan,
            Problem.Field.viewNum,
            Problem.Field.answerNum,
            Problem.Field.askTo,
            Problem.Field.commentNum,
            Problem.Field.tag,
            Problem.Field.timestamp,
            Problem.Field.userId
        ])
        student = User.get({
            User.Field._id: problem.data.get(Problem.Field.userId)
        }, [
            User.Field.name,
            User.Field.avatarUrl
        ])
        ask_to = get_user_or_studio_from_id(problem.data.get(Problem.Field.askTo))
        answers.append({
            '_id': problem.data.get(Problem.Field._id),
            'answer': answer.get(Answer.Field.content)[0].get(Answer.Content.content),
            'answerId': answer_id,
            'askTo': problem.data.get(Problem.Field.askTo),
            'askToAvatarUrl': ask_to.get('avatarUrl'),
            'askToName': ask_to.get('name'),
            'askToType': ask_to.get('uType'),
            Problem.Field.answerNum: problem.data.get(Problem.Field.answerNum),
            Problem.Field.commentNum: problem.data.get(Problem.Field.commentNum),
            Problem.Field.content: problem.data.get(Problem.Field.content),
            Problem.Field.image: problem.data.get(Problem.Field.image),
            User.Field.avatarUrl: student.data.get(User.Field.avatarUrl),
            User.Field.name: student.data.get(User.Field.name),
            Problem.Field.tag: problem.data.get(Problem.Field.tag),
            Problem.Field.timestamp: problem.data.get(Problem.Field.timestamp),
            Problem.Field.userId: problem.data.get(Problem.Field.userId),
            Problem.Field.viewNum: problem.data.get(Problem.Field.viewNum),
            Problem.Field.zan: problem.data.get(Problem.Field.zan)
        })

    return jsonify(stat=1, problems=answers)


@api.route('/studio/<studio_id>/answer/<answer_id>', methods=['PUT'])
def update_studio_answer(studio_id, answer_id):
    '''
## 修改已点评

    PUT /api/studio/<studio_id>/answer/<answer_id>

Parameters:

* `content` (string, required)
    '''
    content = request.form.get('content', '')
    answer = Answer.get({
        Answer.Field._id: answer_id
    }, [
        Answer.Field.content
    ])
    content_list = answer.data.get(Answer.Field.content)
    content_list[0] = {
        Answer.Content.aType: content_list[0].get(Answer.Content.aType),
        Answer.Content.content: content
    }
    answer.update({
        '$set': {
            Answer.Field.content: content_list
        }
    })
    return jsonify(stat=1)


@api.route('/studio/<studio_id>/answer', methods=['POST'])
def new_studio_answer(studio_id):
    """
## 画室点评

    POST /api/studio/<studio_id>/answer

Parameters:

* `content` (string, required) - content of answer
* `problemId` (string, required) - ID of problem

Return:

* `answer` (dict) - info of the answer
    """

    content = request.form.get('content', '')
    problem_id = request.form.get('problemId', None)
    a_type = 2

    if problem_id is None:
        return jsonify(stat=0, **GlobalError.INVALID_PROBLEM_ID), 403

    try:
        problem = Problem.get({
            Problem.Field._id: problem_id
        })
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_PROBLEM_ID), 403

    try:
        studio = Studio.get({
            Studio.Field._id: studio_id
        })
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_USER_ID), 403

    answer_id = Answer.new_answer(studio_id, problem_id, content, a_type)
    problem.update({
        '$push': {
            Problem.Field.answerList: answer_id
        },
        '$inc': {
            Problem.Field.answerNum: 1
        }
    })
    studio.update({
        '$push': {
            Studio.Field.answer: {
                '$each': [answer_id],
                '$position': 0
            }
        },
        '$inc': {
            Studio.Field.answerNum: 1
        },
        '$pull': {
            Studio.Field.askMeList: problem_id
        }
    })

    try:
        answer = Answer.get({
            Answer.Field._id: answer_id
        })
    except:
        print 'Can not find after insert'
        return jsonify(stat=1)

    return jsonify(stat=1, answer=answer.data)


@api.route('/studio/<studio_id>/studio-comment', methods=['GET'])
def get_studio_studio_comment(studio_id):
    '''
## 分页获取画室的学员评论

    GET /api/studio/<studio_id>/studio-comment

Parameters:

* `skip` (int, optional) - 默认为 0
* `total` (int, optional) - 默认为 20，-1表示返回全部

Return:

* `studioComments` (list of dict)
    * `_id` (ObjectId) - Object ID of comment
    * `fromUserId` (string) - 评论者的 ID
    * `fromUserName` (string)
    * `fromUserAvatarUrl` (string)
    * `content` (string) - content of comment
    * `reply` (string) - 画室的回复
    * `timestamp` (long) - timestamp of comment
    * `studioId` (string) - 这条评论是哪个画室下的
    '''
    try:
        Studio.get({Studio.Field._id: studio_id}, [])
    except NotFound:
        return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403
    skip = request.args.get('skip', 0, type=int)
    limit = request.args.get('total', 20, type=int)
    if limit == -1:
        studio_comment_list = StudioComment.find({
            StudioComment.Field.studioId: studio_id
        }, skip=skip, sort=[(StudioComment.Field.timestamp, -1)])
    else:
        studio_comment_list = StudioComment.find({
            StudioComment.Field.studioId: studio_id
        }, skip=skip, limit=limit, sort=[(StudioComment.Field.timestamp, -1)])
    studio_comments = []
    for studio_comment in studio_comment_list:
        try:
            user = User.get({
                User.Field._id: studio_comment.get(StudioComment.Field.fromUserId)
            }, [
                User.Field.name,
                User.Field.avatarUrl
            ])
        except:
            continue
        studio_comments.append({
            StudioComment.Field._id: studio_comment.get(StudioComment.Field._id),
            StudioComment.Field.fromUserId: studio_comment.get(StudioComment.Field.fromUserId),
            'fromUserName': user.data.get(User.Field.name),
            'fromUserAvatarUrl': user.data.get(User.Field.avatarUrl),
            StudioComment.Field.content: studio_comment.get(StudioComment.Field.content),
            StudioComment.Field.reply: studio_comment.get(StudioComment.Field.reply),
            StudioComment.Field.timestamp: studio_comment.get(StudioComment.Field.timestamp),
            StudioComment.Field.studioId: studio_comment.get(StudioComment.Field.studioId)
        })

    return jsonify(stat=1, studioComments=studio_comments)


@api.route('/studio/<studio_id>/studio-comment/<studio_comment_id>', methods=['PUT'])
def reply_studio_comment(studio_id, studio_comment_id):
    '''
## 画室回复学员评论

    PUT /api/studio/<studio_id>/studio-comment/<studio_comment_id>

Parameters:

* `reply` (string, required) - 回复内容
    '''
    reply = request.form.get('reply', None)
    if reply is None:
        return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403
    try:
        StudioComment.collection.update({
            StudioComment.Field._id: studio_comment_id
        }, {
            '$set': {
                StudioComment.Field.reply: reply
            }
        })
    except NotFound:
        return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403

    return jsonify(stat=1)


@api.route('/studio/<studio_id>/studio-comment/<studio_comment_id>', methods=['DELETE'])
def delete_studio_comment(studio_id, studio_comment_id):
    '''
## 画室删除学员评论

    DELETE /api/studio/<studio_id>/studio-comment/<studio_comment_id>
    '''
    try:
        StudioComment.remove({
            StudioComment.Field._id: studio_comment_id
        })
    except:
        return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403
    return jsonify(stat=1)


@api.route('/studio/<studio_id>/environment', methods=['PUT'])
def update_studio_environment(studio_id):
    '''
## 上传画室环境图片

    PUT /api/studio/<studio_id>/environment

Parameters:

* `imageUrls` (string, required) - 图片 url
    '''
    image_urls = request.form.get('imageUrls', None)
    image_urls = json.loads(image_urls)
    if image_urls is None:
        return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403
    try:
        studio = Studio.get({
            Studio.Field._id: studio_id
        }, [
            Studio.Field.environment
        ])
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403

    env_list = studio.data.get(Studio.Field.environment)
    image_urls = filter(lambda x: x not in env_list, image_urls)
    studio.update({
        '$push': {
            Studio.Field.environment: {
                '$each': image_urls,
                '$position': 0
            }
        }
    })
    return jsonify(stat=1)


@api.route('/studio/<studio_id>/environment', methods=['GET'])
def get_studio_environment(studio_id):
    '''
## 获取画室环境

    GET /api/studio/<studio_id>/environment

Return:

* `environment` (list of string) - list of image url
    '''
    try:
        studio = Studio.get({
            Studio.Field._id: studio_id
        }, [
            Studio.Field.environment
        ])
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403

    return jsonify(stat=1, environment=studio.data.get(Studio.Field.environment, []))


@api.route('/studio/<studio_id>/environment', methods=['DELETE'])
def delete_studio_environment(studio_id):
    '''
## 删除画室环境

    DELETE /api/studio/<studio_id>/environment

Parameters:

* `imageUrl` (string, required)
    '''
    image_url = request.args.get('imageUrl', None) or request.form.get('imageUrl', None)
    if image_url is None:
        return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403
    try:
        Studio.collection.update({
            Studio.Field._id: studio_id
        }, {
            '$pull': {
                Studio.Field.environment: image_url
            }
        })
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403
    return jsonify(stat=1)


@api.route('/studio/<studio_id>/avatar', methods=['PUT'])
def update_studio_avatar(studio_id):
    '''
## 更新画室头像

    PUT /api/studio/<studio_id>/avatar

Parameters:

* `avatarUrl` (string, required)
    '''
    avatar_url = request.form.get('avatarUrl', None)
    if avatar_url is None:
        return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403
    try:
        Studio.collection.update({
            Studio.Field._id: studio_id
        }, {
            '$set': {
                Studio.Field.avatarUrl: avatar_url
            }
        })
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403
    return jsonify(stat=1)


@api.route('/studio/<studio_id>/<article_id>', methods=['PUT'])
def edit_article(studio_id, article_id):
    '''
## 编辑文章

    PUT /api/studio/<studio_id>/<article_id>

Parameters:

* `title` (required) - 标题
* `content` (required) - 内容
* `images` (JSON string, optional) - JSON 序列化的图片链接列表

Return:

* `stat` (boolean)
    '''
    title = request.form.get('title', None)
    content = request.form.get('content', None)
    images = json.loads(request.form.get('images'))
    print images
    if title is None or content is None or studio_id is None or article_id is None:
        return  jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403

    try:
        studio = Studio.get({
            Studio.Field._id: studio_id
        })
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403

    try:
        article = Article.get({
            Article.Field._id: article_id
        })
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403

    article.update(
        {
            '$set': {
                Article.Field.title: title,
                Article.Field.content: content,
                Article.Field.images: images
            }
        }
    )

    return jsonify(stat=1)

@api.route('/studio/<studio_id>/<article_id>', methods=['DELETE'])
def del_article(studio_id, article_id):
    '''
## 删除文章

    DELETE /api/studio/<studio_id>/<article_id>

Return:

* `stat` (boolean)
    '''
    if studio_id is None or article_id is None:
        return  jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403

    try:
        studio = Studio.get({
            Studio.Field._id: studio_id
        })
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403

    try:
        article = Article.get({
            Article.Field._id: article_id
        })
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403

    article.remove(
        { Article.Field._id: article_id },
    )

    update_info = {}
    update_info['$pull'] = {Studio.Field.article: article_id}
    update_info['$inc'] = {Studio.Field.articleNum: -1}
    studio.update(update_info)

    return jsonify(stat=1)


@api.route('/studio/teacherIntro/<studio_id>', methods=['GET'])
def get_teacher_intro(studio_id):
    '''
## 获取画室的师资介绍

    GET /studio/teacherIntro/<studio_id>

Parameters:

* `studio_id` (string)

Return:

* `intro`(string): 画室的师资介绍
    '''

    if studio_id is None:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403

    try:
        intro = Studio.find(
            { Studio.Field._id: studio_id },
            {
                Studio.Field.teacherIntro: 1,
                Studio.Field._id: 0
            }
        )
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403

    print(len(intro));
    if len(intro) > 0:
        return jsonify(stat=1, intro=intro[0].get('teacherIntro', "Nothing now"))
    else:
        return jsonify(stat=1, intro="Nothing now")


@api.route('/studio/teacherIntro/<studio_id>', methods=['PUT'])
def edit_teacher_intro(studio_id):
    '''
## 修改画室的师资介绍

    PUT /studio/teacherIntro/<studio_id>

Parameters:

* `studio_id` (string)
* `intro` (string): 作为put的参数传过来，而不是url的

Return:

* `intro` (string): 师资介绍
* `stat` (boolean): 是否成功的标志
    '''

    intro = request.form.get('intro')
    if intro is None:
        return jsonify(stat=0, **GlobalError.PARAMETERS_INVALID), 403

    if studio_id is None:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403

    try:
        studio = Studio.get(
            { Studio.Field._id: studio_id }
        )
    except NotFound:
        return jsonify(stat=0, **GlobalError.INVALID_STUDIO_ID), 403

    studio.update({
        '$set': { Studio.Field.teacherIntro: intro }
    })

    return jsonify(stat=1, intro=intro)

